#include "loggerprivate.h"

/************************************************
 * 功能：构造函数
 ************************************************/
LoggerPrivate::LoggerPrivate()
{
    m_eDebugLevel = Logging::FATAL;
}

/************************************************
 * 功能：载入配置
 ************************************************/
void LoggerPrivate::load( Logging::RotateConfigInfo* pInfo )
{
    m_eLogLevel = pInfo->eLogLevel;

    switch( pInfo->eBackupType )
    {
        case Logging::BACKUP_BY_MAXBYTES:
        {
            QsLogging::DestinationPtr destination( QsLogging::DestinationFactory::MakeFileDestination(
                                                       pInfo->strFileName,
                                                       QsLogging::EnableLogRotation,
                                                       QsLogging::MaxSizeBytes(pInfo->iMaxCountOrBytes),
                                                       QsLogging::MaxOldLogCount(pInfo->iMaxBackupFileCount) ) );
            addDestination( destination );
        }
            break;
        case Logging::BACKUP_BY_MAXCOUNT:
        {
            QsLogging::DestinationPtr destination( QsLogging::DestinationFactory::MakeFileDestination(
                                                       pInfo->strFileName,
                                                       QsLogging::EnableLogRotation,
                                                       QsLogging::MaxNumber(pInfo->iMaxCountOrBytes),
                                                       QsLogging::MaxOldLogCount(pInfo->iMaxBackupFileCount) ) );
            addDestination( destination );
        }
            break;
        default:
            qWarning() << "LoggerPrivate::load: error, invalid backup type " << pInfo->eBackupType;
            break;
    }
}
/************************************************
 * 功能：载入配置
 ************************************************/
void LoggerPrivate::load( Logging::TimeConfigInfo* pInfo )
{
    qDebug() << "LoggerPrivate::load START";
    m_eLogLevel = pInfo->eLogLevel;

    switch( pInfo->eBackupType )
    {
        case Logging::BACKUP_BY_DAY:
        {
            qDebug() << "Creating BACKUP_BY_DAY destination...";
            qDebug() << "  FilePath:" << pInfo->strFilePath;
            qDebug() << "  Suffix:" << pInfo->strSuffix;
            qDebug() << "  MaxBytes:" << pInfo->iMaxTotalFileBytes;
            qDebug() << "Calling MakeFileDestination...";
            QsLogging::DestinationPtr destination( QsLogging::DestinationFactory::MakeFileDestination(
                                                       pInfo->strFilePath,
                                                       Logging::FILE_FORMAT_BY_DATE,
                                                       pInfo->strSuffix,
                                                       pInfo->iMaxTotalFileBytes,
                                                       pInfo->fRecyclePercent ) );
            qDebug() << "MakeFileDestination returned, adding destination...";
            addDestination( destination );
            qDebug() << "Destination added successfully";
        }
            break;
        case Logging::BACKUP_BY_MONTH:
        {
            QsLogging::DestinationPtr destination( QsLogging::DestinationFactory::MakeFileDestination(
                                                       pInfo->strFilePath,
                                                       Logging::FILE_FORMAT_BY_MONTH,
                                                       pInfo->strSuffix,
                                                       pInfo->iMaxTotalFileBytes,
                                                       pInfo->fRecyclePercent ) );
            addDestination( destination );
        }
            break;
        case Logging::BACKUP_BY_YEAR:
        {
            QsLogging::DestinationPtr destination( QsLogging::DestinationFactory::MakeFileDestination(
                                                       pInfo->strFilePath,
                                                       Logging::FILE_FORMAT_BY_YEAR,
                                                       pInfo->strSuffix,
                                                       pInfo->iMaxTotalFileBytes,
                                                       pInfo->fRecyclePercent ) );
            addDestination( destination );
        }
            break;
        default:
            qWarning() << "LoggerPrivate::load: error, invalid backup type " << pInfo->eBackupType;
            break;
    }
}

/************************************************
 * 功能：保存数据
 * 输入参数：
 *      level -- 日志等级
 *      data -- 日志数据
 ************************************************/
void LoggerPrivate::write( Logging::LogLevel level, const QString& data )
{
    QMutexLocker lock(&m_mutex);
    bool bDebugValid = ( ( !m_destDebug.isNull() ) && (level >= m_eDebugLevel ) );
    if( ( level >= m_eLogLevel ) || bDebugValid )
    {
        const char* const levelName = Logging::LevelToText(level);
        const QString completeMessage(QString("%1 %2 %3")
                                      .arg(levelName)
                                      .arg(QDateTime::currentDateTime().toString(Logging::DATETIME_FORMAT))
                                      .arg(data)
                                      );

        for( Logging::DestinationList::iterator it = m_destList.begin(),endIt = m_destList.end();it != endIt;++it)
        {
            (*it)->write(completeMessage, (QsLogging::Level)level);
        }

        //调试输出
        if( bDebugValid )
        {
            m_destDebug->write( completeMessage, (QsLogging::Level)level );
        }
    }
}

/************************************************
 * 功能：添加存储目标地址
 * 输入参数：
 *      destination -- 存储地址
 ************************************************/
void LoggerPrivate::addDestination( QsLogging::DestinationPtr destination )
{
    QMutexLocker lock( &m_mutex );
    m_destList.push_back(destination);
}

/************************************************
 * 功能：去除存储目标地址
 * 输入参数：
 *      destination -- 存储地址
 ************************************************/
void LoggerPrivate::removeDestination( QsLogging::DestinationPtr destination )
{
    QMutexLocker lock(&m_mutex);
    const int destinationIndex = m_destList.indexOf(destination);
    if (destinationIndex != -1)
    {
        m_destList.remove(destinationIndex);
    }
}
